package org.share.comm.net;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * upd 服务端创建
 * @author hhm
 *
 */
public class UDPServer implements Runnable {
	
	private static final Logger _logger = LoggerFactory.getLogger(UDPServer.class);
	
	//缓冲区大小
	private final int BUFFER_SIZE = 2048;
	//缓冲区数组
	private byte[] packetBuffer = new byte[BUFFER_SIZE];
	//udp服务器对象
	private DatagramSocket udpServer = null;  
	//数据包
    private DatagramPacket packet = null;  
    private UDPReceiveDealThread receiveDeal = null; 
    
    /**
     * 启动UDP服务器监听
     * @param port 
     * @param receiveDeal
     */
    public static void listen(int port,UDPReceiveDealThread receiveDeal){
    	Thread listen = new Thread(new UDPServer(port,receiveDeal));
    	listen.setName("UDPServerThread-"+port);
    	listen.start();
    	_logger.info("UDPServer Startup Listen : "+port);
    }
    
    private UDPServer(int port,UDPReceiveDealThread receiveDeal){
    	this.receiveDeal = receiveDeal;
    	init(port);
    }
    
    private void init(int port){
    	try {
			udpServer = new DatagramSocket(port);
			packet = new DatagramPacket(packetBuffer,BUFFER_SIZE);
		} catch (SocketException e) {
			_logger.error("UDPServer create failure! ",e);
			throw new RuntimeException("UDPServer create failure! ",e);
		}
    }
    
	@Override
	public void run() {
		for(;;){
			
			try {
				udpServer.receive(packet);
				_logger.info("UDPServer receive packet size : "+packet.getLength());
				
				//拷贝数据到新的数组中
				final byte[] data = new byte[packet.getLength()];
				System.arraycopy(packet.getData(), 0, data, 0, packet.getLength());
				
				//启动线程处理接受到到数据
				new Thread(new Runnable(){
					@Override
					public void run() {
						receiveDeal.deal(data);
					}
				}).start();
				
			} catch (IOException e) {
				_logger.warn("UDPServer receive exception.",e);
			}
		}
	}
	
	/**
	 * 线程处理调用接口
	 * @author hhm
	 *
	 */
	public interface UDPReceiveDealThread{
		//线程处理执行方法
		void deal(byte[] data);
	}

}
